package com.websuites.proxy;

import java.io.IOException;

import javax.servlet.ServletInputStream;

public class Chunk
{
	public static final int CHUNK_SIZE = 4096;
	private static Chunk head;
	private boolean isFree;
	private Chunk next;
	private byte[] buf;
	private int end;
	private static int allocated;
	private static int freed;
	
	private Chunk(int paramInt)
	{
		this.end = 0;
		this.buf = new byte[paramInt];
	}
	
	public byte[] getBuffer()
	{
		return this.buf;
	}

	public int getBufferSize()
	{
		return this.buf.length;
	}

	public int size()
	{
		return this.end;
	}

	public static synchronized Chunk alloc() 
	{
	    Chunk localChunk = head;
	    if (head != null) 
	    {
	    	head = head.next;
	    	localChunk.isFree = false;
	    	return localChunk;
	    }
	
	    allocated += 1;
	    System.out.println("Allocating new Chunk, alloc count=" + allocated + "free count=" + freed);
	
	    return new Chunk(Chunk.CHUNK_SIZE);
	}

	public static synchronized Chunk getChunk() 
	{
		return alloc();
	}
	
	public static synchronized void free(Chunk paramChunk) 
	{
		freed += 1;
		if (paramChunk.isFree) 
		{
			throw new AssertionError();
		}
		paramChunk.isFree = true;
		paramChunk.end = 0;
		paramChunk.next = head;
		head = paramChunk;
	}

	public void free() 
	{
		free(this);
	}

	static
	{
		for (int i = 0; i < 10000; i++) 
		{
			Chunk localChunk = new Chunk(Chunk.CHUNK_SIZE);
			free(localChunk);
		}
	}
	
	public int read(ServletInputStream servletInputStream, int size) throws IOException
	{
		int read = 0;
		while ((read = servletInputStream.read(this.buf, this.end, CHUNK_SIZE - this.end)) != -1)
		{
			this.end += read;
		}
		return this.end;
	}
}
